package com.ts.api.module.match.plan.internal.qualification.strategy;

import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.valid.ValidParam;
import com.ts.api.common.constant.api.ApiEnum;
import com.ts.api.common.constant.common.SwitchEnum;
import com.ts.api.common.constant.product.ProductPlanTypeEnum;
import com.ts.api.common.constant.product.ProductPlanVersionEnum;
import com.ts.api.common.localcache.DistrictCache;
import com.ts.api.exp.ApiMsgException;
import com.ts.api.module.api.entity.ApiUserRequest;
import com.ts.api.module.api.entity.po.ApiKeyPO;
import com.ts.api.module.channel.entity.po.ChannelUserFormFieldPO;
import com.ts.api.module.channel.entity.po.ChannelUserRegisterPO;
import com.ts.api.module.common.entity.DistrictPO;
import com.ts.api.module.match.plan.internal.qualification.model.PlanQualification;
import com.ts.api.module.match.plan.internal.qualification.model.PlanQualificationResult;
import com.ts.api.module.match.plan.model.ApiWakePlanMatch;
import com.ts.api.module.product.entity.po.ProductPlanPO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 *  唤醒模式资质验证
 *
 *  @author Pan
 */
@Service
public class WakeChannelQualification implements PlanQualificationStrategy<ApiWakePlanMatch> {

    @Autowired
    private BaseQualification baseQualification;

    @Override
    public PlanQualification convert(ApiWakePlanMatch apiWakePlanMatch) {
        String reqId = apiWakePlanMatch.getReqId();

        ApiKeyPO apiKeyPO = apiWakePlanMatch.getApiKeyPO();

        //  获取用户表单+用户信息
        List<ChannelUserFormFieldPO> listUserForm = apiWakePlanMatch.getListUserForm();
        ChannelUserRegisterPO channelUserRegisterPO = apiWakePlanMatch.getChannelUserRegisterPO();

        //  根据用户信息转换apiUserInfo对象
        ApiUserRequest apiUserRequest = ApiUserRequest.convert(channelUserRegisterPO, listUserForm);
        apiUserRequest.setReqId(reqId);
        apiUserRequest.setApiClientId(apiKeyPO.getApiClientId());
        apiUserRequest.setLoanChannelId(apiKeyPO.getLoanChannelId());
        apiUserRequest.setEnvType(apiKeyPO.getApiEnvType());

        //  设置城市信息
        DistrictPO districtPO = DistrictCache.getByName(channelUserRegisterPO.getAreaName());
        apiUserRequest.setAreaCode(districtPO.getCode());
        apiUserRequest.setCity(districtPO.getName());
        apiUserRequest.setProvinceName(districtPO.getProvinceName());
        apiUserRequest.setProvinceCode(districtPO.getProvinceCode());

        //  转换资质实体
        PlanQualification planQualification = new PlanQualification();
        planQualification.setReqId(reqId);
        planQualification.setApiUserRequest(apiUserRequest);
        planQualification.setListPlanType(apiWakePlanMatch.getListPlanType());
        planQualification.setEnableFilterDistributeByUser(true);
        return planQualification;
    }

    @Override
    public PlanQualificationResult filter(PlanQualification planQualification, ApiWakePlanMatch apiWakePlanMatch) {
        String reqId = planQualification.getReqId();
        ApiUserRequest apiUserRequest = planQualification.getApiUserRequest();

        //  1.验证城市是否为空
        DistrictPO districtPO = baseQualification.validArea(planQualification);
        if (ValidParam.isNull(districtPO)) {
            return PlanQualificationResult.ofFail(new ApiMsgException(ApiEnum.API_DATA_EXCHANGE_AREA_ERROR));
        }

        //  2.过滤计划类型
        List<ProductPlanPO> listPlan = baseQualification.filterPlanType(planQualification, apiWakePlanMatch);
        if (ValidParam.isEmpty(listPlan)) {
            return PlanQualificationResult.ofFail(new ApiMsgException(ApiEnum.API_DATA_EXCHANGE_MATCH_AREA_EMPTY));
        }

        //  3.验证当前时间符合计划时间
        List<ProductPlanPO> listPlanOpenTime = baseQualification.validOpenTime(listPlan);
        if (ValidParam.isEmpty(listPlanOpenTime)) {
            return PlanQualificationResult.ofFail(new ApiMsgException(ApiEnum.API_DATA_EXCHANGE_MATCH_PLAN_TIME_EMPTY));
        }

        //  4.渠道匹配模式验证
        List<ProductPlanPO> listVersionPlan = CollUtils.find(listPlanOpenTime, productPlanPO -> {
            Integer planType = productPlanPO.getPlanType();
            Integer versionType = productPlanPO.getVersionType();

            //  针对-所有机构计划唤醒
            if (ProductPlanTypeEnum.ORG.hasType(planType)) {
                return true;
            }

            //  只针对-平台计 ->全流程模式唤醒
            if (ProductPlanTypeEnum.PLATFORM.hasType(planType) && ProductPlanVersionEnum.ALL.hasVersion(versionType)) {
                return true;
            }
            return false;
        });
        if (ValidParam.isEmpty(listVersionPlan)) {
            return PlanQualificationResult.ofFail(new ApiMsgException(ApiEnum.API_DATA_EXCHANGE_MATCH_EMPTY));
        }

        //  5.找到可唤醒计划列表
        List<ProductPlanPO> listEnableWake = CollUtils.find(listVersionPlan, productPlanPO -> SwitchEnum.hasEnable(productPlanPO.getEnableFilterLocal()));
        if (ValidParam.isEmpty(listEnableWake)) {
            return PlanQualificationResult.ofFail(new ApiMsgException(ApiEnum.API_DATA_EXCHANGE_MATCH_EMPTY));
        }

        //  6.过滤用户资质与当前匹配计划资质不符合项
        List<ProductPlanPO> listQualificationPlan = baseQualification.filterUserField(listEnableWake, apiUserRequest);
        if (ValidParam.isEmpty(listQualificationPlan)) {
            return PlanQualificationResult.ofFail(new ApiMsgException(ApiEnum.API_DATA_EXCHANGE_MATCH_EMPTY));
        }

        //  7.过滤当前用户已被本地crm分发过的计划
        Long userId = apiUserRequest.getUserId();
        List<ProductPlanPO> listFilterDistributeLocalCrm = baseQualification.filterDistributeLocalCrm(listQualificationPlan, userId);
        if (ValidParam.isEmpty(listFilterDistributeLocalCrm)) {
            return PlanQualificationResult.ofFail(new ApiMsgException(ApiEnum.API_DATA_EXCHANGE_MATCH_FAIL2));
        }

        //  8.获取最终过滤条件
        List<ProductPlanPO> finalPlanQualifications = listFilterDistributeLocalCrm;

        //  返回验证通过实体
        PlanQualificationResult planQualificationResult = new PlanQualificationResult();
        planQualificationResult.setReqId(reqId);
        planQualificationResult.setApiUserRequest(apiUserRequest);
        planQualificationResult.setAbstractPlanMatch(apiWakePlanMatch);
        planQualificationResult.setListPlanQualification(finalPlanQualifications);
        return planQualificationResult;
    }
}
